package com.smart.sso.server.controller;

import com.alibaba.fastjson.JSONObject;
import com.smart.mvc.model.Result;
import com.smart.mvc.model.ResultCode;
import com.smart.mvc.util.StringUtils;
import com.smart.mvc.validator.Validator;
import com.smart.mvc.validator.annotation.ValidateParam;
import com.smart.sso.client.SsoFilter;
import com.smart.sso.server.captcha.CaptchaHelper;
import com.smart.sso.server.common.LoginUser;
import com.smart.sso.server.common.TokenManager;
import com.smart.sso.server.controller.common.BaseController;
import com.smart.sso.server.dto.response.QiyeWeiXinVo;
import com.smart.sso.server.enums.WechatConfig;
import com.smart.sso.server.model.User;
import com.smart.sso.server.provider.IdProvider;
import com.smart.sso.server.provider.PasswordProvider;
import com.smart.sso.server.service.UserService;
import com.smart.sso.server.util.CodeUtil;
import com.smart.sso.server.util.CookieUtils;
import com.smart.sso.server.util.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;


/**
 * @author Joe
 */
@Api(tags = "单点登录管理")
@Controller
@RequestMapping("/login")
public class LoginController extends BaseController{
	
	// 登录页
	private static final String LOGIN_PATH = "/login";
	// 手动登录页
	private static final String LOGIN_OLD_PATH = "/loginOld";
	@Resource
	private TokenManager tokenManager;
	@Resource
	private UserService userService;

	@ApiOperation("登录页")
	@RequestMapping(method = RequestMethod.GET)
	public String login(
			@ApiParam(value = "返回链接", required = true) @ValidateParam({ Validator.NOT_BLANK }) String backUrl,
			HttpServletRequest request,Model model) {
		String token = CookieUtils.getCookie(request, TokenManager.TOKEN);
		
		if (StringUtils.isNotBlank(token) && tokenManager.validate(token) != null) {
			return "redirect:" + authBackUrl(backUrl, token);
		}
		else {
			//企业微信登录前端回调地址即为backUrl
			model.addAttribute("frontBackUrl", backUrl);
			return goLoginPath(backUrl, request);
		}
	}

	@ApiOperation("账号登录页")
	@RequestMapping(value = "/old", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
	public String loginOld(
			@ApiParam(value = "返回链接", required = false)  String backUrl,
			HttpServletRequest request) {
		String token = CookieUtils.getCookie(request, TokenManager.TOKEN);
		//返回链接为空是跳转到crm系统
		if(StringUtils.isBlank(backUrl)) {
			backUrl="https://admin.boluozaixian.com/boluo-crm/index";
		}
		if (StringUtils.isNotBlank(token) && tokenManager.validate(token) != null) {
			return "redirect:" + authBackUrl(backUrl, token);
		}
		else {
			return goOldLoginPath(backUrl, request);
		}
	}
	@ApiOperation("登录提交")
	@RequestMapping(method = RequestMethod.POST)
	public String login(
			@ApiParam(value = "返回链接", required = true) @ValidateParam({ Validator.NOT_BLANK }) String backUrl,
			@ApiParam(value = "登录名", required = true) @ValidateParam({ Validator.NOT_BLANK }) String account,
			@ApiParam(value = "密码", required = true) @ValidateParam({ Validator.NOT_BLANK }) String password,
			@ApiParam(value = "验证码", required = true) @ValidateParam({ Validator.NOT_BLANK }) String captcha,
			HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
		if (!CaptchaHelper.validate(request, captcha)) {
			request.setAttribute("errorMessage", "验证码不正确");
			return goOldLoginPath(backUrl, request);
		}
		Result result = userService.login(getIpAddr(request), account, PasswordProvider.encrypt(password));
		if (!result.getCode().equals(ResultCode.SUCCESS)) {
			request.setAttribute("errorMessage", result.getMessage());
			return goOldLoginPath(backUrl, request);
		}
		else {
			User user = (User) result.getData();
			LoginUser loginUser = new LoginUser(user.getId(), user.getAccount(),user.getRealName());
		
			String token = CookieUtils.getCookie(request, TokenManager.TOKEN);
			
			if (StringUtils.isBlank(token) || tokenManager.validate(token) == null) {// 没有登录的情况
				token = createToken(loginUser);
				addTokenInCookie(token, request, response);
			}
			// 跳转到原请求
			backUrl = URLDecoder.decode(backUrl, "utf-8");
			return "redirect:" + authBackUrl(backUrl, token);
		}
	}
	
	private String goLoginPath(String backUrl, HttpServletRequest request) {
		request.setAttribute("backUrl", backUrl);
		return LOGIN_PATH;
	}
	private String goOldLoginPath(String backUrl, HttpServletRequest request) {
		request.setAttribute("backUrl", backUrl);
		return LOGIN_OLD_PATH;
	}
	private String authBackUrl(String backUrl, String token) {
		StringBuilder sbf = new StringBuilder(backUrl);
		if (backUrl.indexOf("?") > 0) {
			sbf.append("&");
		}
		else {
			sbf.append("?");
		}
		sbf.append(SsoFilter.SSO_TOKEN_NAME).append("=").append(token);
		return sbf.toString();
	}

	private String createToken(LoginUser loginUser) {
		// 生成token
		String token = IdProvider.createUUIDId();

		// 缓存中添加token对应User
		tokenManager.addToken(token, loginUser);
		return token;
	}
	
	private void addTokenInCookie(String token, HttpServletRequest request, HttpServletResponse response) {
		// Cookie添加token
		Cookie cookie = new Cookie(TokenManager.TOKEN, token);
		cookie.setPath("/");
		if ("https".equals(request.getScheme())) {
			cookie.setSecure(true);
		}
		cookie.setHttpOnly(true);
		response.addCookie(cookie);
	}
	/**
	 * 企业微信扫码登录
	 * @return
	 */
	@RequestMapping(value = "/qiyeWxLogin", method = RequestMethod.GET)
	public String  weiXinLogin(String code, String state, String appid,String backUrl,
							   HttpServletRequest request,HttpServletResponse response) {
		try {
			//获取企业微信用户ID
			String tokenJson = HttpUtil.get("https://qyapi.weixin.qq.com/cgi-bin/gettoken",
					"corpid=" + WechatConfig.QIYE_APPID + "&corpsecret=" + WechatConfig.QIYE_SECRET);
			String accessToken = (String) JSONObject.parseObject(tokenJson).get("access_token");

			String userJson = HttpUtil.get("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo",
					"access_token=" + accessToken + "&code=" + code);
			logger.info("[login]---qiyeWxLogin---userJson={},backUrl={}",userJson,backUrl);
			String qiyeWxUserId = (String) JSONObject.parseObject(userJson).get("UserId");

			if(StringUtils.isBlank(qiyeWxUserId)) {
				return goLoginPath(backUrl, request);
			}
			// 根据企业微信用户ID查询用户信息
            User user = this.userService.findByQiyeWxUserId(qiyeWxUserId);
            if(user==null) {
				request.setAttribute("errorMessage", "用户不存在");
				return goLoginPath(backUrl, request);
            }
            //进行登陆数据检测并更新
			 userService.login(getIpAddr(request), user.getAccount(), user.getPassword());
			LoginUser loginUser = new LoginUser(user.getId(), user.getAccount(),user.getRealName());
			// 生成token
			String token = CookieUtils.getCookie(request, TokenManager.TOKEN);
			if (StringUtils.isBlank(token) || tokenManager.validate(token) == null) {// 没有登录的情况
				token = createToken(loginUser);
				addTokenInCookie(token, request, response);
			}
			if(StringUtils.isNotBlank(backUrl)){
				// 跳转到原请求
				backUrl = URLDecoder.decode(backUrl, "utf-8");
				return "redirect:" + authBackUrl(backUrl, token);
			}
			return goLoginPath(backUrl, request);
		} catch (Exception e) {
			request.setAttribute("errorMessage","登陆失败" + e.getMessage());
			logger.error("[login]---qiyeWxLogin---企业微信登录异常",e);
			return goLoginPath(backUrl, request);
		}
	}

	/**
	 *
	 * @param backUrl 请求接口之后的回调地址
	 * @return
	 */
	@RequestMapping(value = "/qiyeWxLoginData",method = RequestMethod.GET)
	@ResponseBody
	public Result qiyeWxLoginData(@ApiParam(value = "返回链接", required = true) @ValidateParam({ Validator.NOT_BLANK })String backUrl) {
		Result result = Result.createSuccessResult();
		try {
			QiyeWeiXinVo vo = new QiyeWeiXinVo();
			vo.setId(WechatConfig.QIYE_LOGIN_ID);
			vo.setAppid(WechatConfig.QIYE_APPID);
			vo.setAgentid(WechatConfig.QIYE_AGENTID);
			String redirectUri = URLEncoder.encode(WechatConfig.QIYE_REDIRECT_URI + "?backUrl=" + backUrl, "utf-8");
			vo.setRedirect_uri(redirectUri);
			vo.setState(CodeUtil.getRandom(6));
			vo.setHref("");
			return result.setData(vo);
		} catch (Exception e) {

			return result.setCode(ResultCode.ERROR).setMessage(e.getMessage());
		}
	}
}